`include "ascon_define.v"

module `TX_BUF_4_32B_64
    (
    input                                        clk_i,
    input                                        rstn_i,

    input                                        en_i,
    input                                        wen_i,
    input                   [`BUF_ADDR_W+1-1 :0] waddr_i,
    input                            [`P_W-1 :0] wdata_i,
    input                                        mode_i,

    input                  [`AHB_BUS_ADDR_W-1:0] raddr_i,
    output reg             [`AHB_BUS_DATA_W-1:0] rdata_o
    );

wire                                             en_0 , en_1, en_2 , en_3;
wire                                             wen_0  , wen_1, wen_2  , wen_3;
wire                       [`AHB_BUS_DATA_W-1:0] rdata_0, rdata_1, rdata_2, rdata_3;
wire                       [`AHB_BUS_DATA_W-1:0] wdata_0, wdata_1, wdata_2, wdata_3;

wire                           [`BUF_ADDR_W-1:0] waddr;
wire                                       [0:0] wByte_sel;

wire                           [`BUF_ADDR_W-1:0] raddr;
wire                                       [1:0] rByte_sel;

assign waddr                                     = waddr_i[`BUF_ADDR_W:1];
assign wByte_sel                                 = waddr_i[0:0];

assign raddr                                     = raddr_i[4+`BUF_ADDR_W-1:4];
assign rByte_sel                                 = raddr_i[3:2];

assign en_0                                      = (mode_i == 1'b0) ? (en_i) : ((wByte_sel == 1'b0) ? en_i : 1'b0);
assign en_1                                      = (mode_i == 1'b0) ? (en_i) : ((wByte_sel == 1'b0) ? en_i : 1'b0);
assign en_2                                      = (mode_i == 1'b0) ? (en_i) : ((wByte_sel == 1'b0) ? 1'b0 : en_i);
assign en_3                                      = (mode_i == 1'b0) ? (en_i) : ((wByte_sel == 1'b0) ? 1'b0 : en_i);

assign wen_0                                     = (mode_i == 1'b0) ? (wen_i) : ((wByte_sel == 1'b0) ? wen_i : 1'b0);
assign wen_1                                     = (mode_i == 1'b0) ? (wen_i) : ((wByte_sel == 1'b0) ? wen_i : 1'b0);
assign wen_2                                     = (mode_i == 1'b0) ? (wen_i) : ((wByte_sel == 1'b0) ? 1'b0 : wen_i);
assign wen_3                                     = (mode_i == 1'b0) ? (wen_i) : ((wByte_sel == 1'b0) ? 1'b0 : wen_i);

assign wdata_0                                   = (mode_i == 1'b0) ? (wdata_i[32-1:0]) : ((wByte_sel == 1'b0) ? wdata_i[96-1:64] : `AHB_BUS_DATA_W'b0);
assign wdata_1                                   = (mode_i == 1'b0) ? (wdata_i[64-1:32]) : ((wByte_sel == 1'b0) ? wdata_i[128-1:96] : `AHB_BUS_DATA_W'b0);
assign wdata_2                                   = (mode_i == 1'b0) ? (wdata_i[96-1:64]) : ((wByte_sel == 1'b0) ? `AHB_BUS_DATA_W'b0 : wdata_i[96-1:64]);
assign wdata_3                                   = (mode_i == 1'b0) ? (wdata_i[128-1:96]) : ((wByte_sel == 1'b0) ? `AHB_BUS_DATA_W'b0 : wdata_i[128-1:96]);

always@(*)begin
    case (rByte_sel)
        2'b00 : rdata_o       = rdata_0; // msb->lsb(left->right)
        2'b01 : rdata_o       = rdata_1;
        2'b10 : rdata_o       = rdata_2;
        2'b11 : rdata_o       = rdata_3;
        default : rdata_o    = `AHB_BUS_DATA_W'b0;
    endcase
end

// 第一字节
`RAM_32B_64
u_ram_0
    (
    .clk_i                             (clk_i                                  ),
    .rstn_i                            (rstn_i                                 ),

    .en_i                              (en_0                                   ),
    .wen_i                             (wen_0                                  ),
    .waddr_i                           (waddr                                  ),
    .wdata_i                           (wdata_0                                ),

    .raddr_i                           (raddr                                  ),
    .rdata_o                           (rdata_0                                )
    );

// 第二字节
`RAM_32B_64
u_ram_1
    (
    .clk_i                             (clk_i                                  ),
    .rstn_i                            (rstn_i                                 ),

    .en_i                              (en_1                                   ),
    .wen_i                             (wen_1                                  ),
    .waddr_i                           (waddr                                  ),
    .wdata_i                           (wdata_1                                ),

    .raddr_i                           (raddr                                  ),
    .rdata_o                           (rdata_1                                )
    );

// 第三字节
`RAM_32B_64
u_ram_2
    (
    .clk_i                             (clk_i                                  ),
    .rstn_i                            (rstn_i                                 ),

    .en_i                              (en_2                                   ),
    .wen_i                             (wen_2                                  ),
    .waddr_i                           (waddr                                  ),
    .wdata_i                           (wdata_2                                ),

    .raddr_i                           (raddr                                  ),
    .rdata_o                           (rdata_2                                )
    );

// 第四字节
`RAM_32B_64
u_ram_3
    (
    .clk_i                             (clk_i                                  ),
    .rstn_i                            (rstn_i                                 ),

    .en_i                              (en_3                                   ),
    .wen_i                             (wen_3                                  ),
    .waddr_i                           (waddr                                  ),
    .wdata_i                           (wdata_3                                ),

    .raddr_i                           (raddr                                  ),
    .rdata_o                           (rdata_3                                )
    );
endmodule